// 简易C++ Web服务器
// 编译命令: g++ simple_webserver.cpp -o webserver -lpthread
// 运行: ./webserver
// 访问: http://服务器IP:8080

#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

using namespace std;

// 端口号
#define PORT 8080
// 最大连接数
#define MAX_CONNECTIONS 5
// 缓冲区大小
#define BUFFER_SIZE 4096

// 处理客户端请求的函数
void *handle_client(void *client_socket_ptr) {
    int client_socket = *(int*)client_socket_ptr;
    delete (int*)client_socket_ptr;
    
    char buffer[BUFFER_SIZE] = {0};
    // 读取客户端请求
    read(client_socket, buffer, BUFFER_SIZE);
    cout << "收到请求:\n" << buffer << endl;
    
    // 修正后的HTTP响应构建
    string response = "HTTP/1.1 200 OK\r\n";               // 状态行，必须以\r\n结尾
    response += "Content-Type: text/html; charset=UTF-8\r\n"; // 内容类型
    response += "Content-Length: 128\r\n";                 // 内容长度（需计算实际值）
    response += "Connection: close\r\n";                   // 告诉浏览器连接可关闭
    response += "\r\n";                                    // 空行分隔响应头和内容
    response += "<html><head><title>成功访问</title></head>";
    response += "<body><h1>Hello from C++ Server</h1>";
    response += "<p>浏览器可以正常显示了！</p></body></html>";
    
    // 发送响应
    send(client_socket, response.c_str(), response.size(), 0);
    cout << "已发送响应" << endl;
    
    // 关闭连接
    close(client_socket);
    return nullptr;
}

int main() {
    int server_fd;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    
    // 创建socket文件描述符
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }
    
    // 设置socket选项，允许重用端口和地址
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;  // 监听所有网络接口
    address.sin_port = htons(PORT);       // 设置端口号
    
    // 绑定socket到指定端口
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    
    // 开始监听端口，最大等待连接数为MAX_CONNECTIONS
    if (listen(server_fd, MAX_CONNECTIONS) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    
    cout << "服务器已启动，端口: " << PORT << endl;
    cout << "请在浏览器中访问: http://你的服务器IP:" << PORT << endl;
    cout << "按Ctrl+C停止服务器" << endl;
    
    // 循环接受客户端连接
    while (true) {
        int *client_socket = new int;
        // 接受客户端连接
        if ((*client_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
            perror("accept");
            delete client_socket;
            continue;
        }
        
        cout << "新连接来自: " << inet_ntoa(address.sin_addr) << endl;
        
        // 创建线程处理客户端请求
        pthread_t thread_id;
        if (pthread_create(&thread_id, nullptr, handle_client, client_socket) != 0) {
            perror("pthread_create failed");
            close(*client_socket);
            delete client_socket;
        }
        
        // 分离线程，自动释放资源
        pthread_detach(thread_id);
    }
    
    // 关闭服务器socket（实际不会执行到这里，因为上面是无限循环）
    close(server_fd);
    return 0;
}
